<!doctype html>
<html lang="en-us">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Scroll snap</title>
    <style>
      li {
        /*
        starts with:
           scroll-snap-align: center center;
           scroll-snap-stop: normal (defaults);

        CSS gets changed with JavaScript when you change the controls.
        the following can be set:
            scroll-snap-stop: always | normal;
            scroll-snap-align: start | center | end {2}
        */
      }
      ul {
        overflow: auto;
        scroll-snap-type: both mandatory;
        overscroll-behavior-x: contain;
      }
      article.snapDisabled fieldset {
        opacity: 20%;
        pointer-events: none;
      }
      article.snapDisabled ul {
        scroll-snap-type: initial;
        overscroll-behavior-x: initial;
      }

      @layer pageSetup {
        article {
          display: flex;
          gap: 2vw;
        }
        div {
          flex: 1;
        }
        ul {
          display: grid;
          gap: 6.25vw;
          padding: 12.5vw;
          box-sizing: border-box;
          border: 1px solid;
          grid-template-columns: repeat(5, 1fr);
          background: conic-gradient(
            at bottom left,
            red 0deg,
            yellow 15deg,
            green 30deg,
            blue 45deg,
            purple 60deg,
            magenta 75deg
          );
          background-attachment: local;
          margin: auto;
          width: 20vw;
          height: 20vw;
        }
        li {
          scroll-snap-align: center;
          height: 12.5vw;
          width: 12.5vw;
          outline: 3px inset;
          list-style-type: none;
          background: white;
          font-family: monospace;
          font-size: 3rem;
          line-height: 12vw;
          text-align: center;
          counter-increment: items 1;
        }
        li::after {
          content: counter(items);
        }
        input {
          vertical-align: bottom;
        }
        p {
          font-family: monospace;
        }
      }
    </style>
  </head>

  <body>
    <article>
      <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
      <div>
        <fieldset>
          <legend>Change the options</legend>
          <p>
            <label
              ><input
                type="range"
                min="0"
                max="2"
                value="1"
                list="places"
                id="block" />
              block position</label
            >
          </p>
          <p>
            <label
              ><input
                type="range"
                min="0"
                max="2"
                value="1"
                list="places"
                id="inline" />
              inline position</label
            >
          </p>
          <p>
            <label
              ><input type="checkbox" id="stop" /> Prevent scrolling past
              boxes</label
            >
          </p>
        </fieldset>

        <p>
          <label><input type="checkbox" id="snap" /> disable snapping</label>
        </p>

        <datalist id="places">
          <option value="0">start</option>
          <option value="1">center</option>
          <option value="2">end</option>
        </datalist>
      </div>
    </article>

    <script>
      const positions = ["start", "center", "end"];
      const inlineDirection = document.getElementById("inline");
      const blockDirection = document.getElementById("block");
      const stop = document.getElementById("stop");
      const snap = document.getElementById("snap");
      const all = document.querySelector("article");
      const rules = document.styleSheets[0].cssRules;

      inlineDirection.addEventListener("change", () => {
        setSSA();
      });
      blockDirection.addEventListener("change", () => {
        setSSA();
      });
      stop.addEventListener("change", () => {
        setSST();
      });
      window.addEventListener("load", () => {
        setSST();
        setSSA();
      });
      snap.addEventListener("change", () => {
        all.classList.toggle("snapDisabled");
      });

      function setSSA() {
        rules[0].style.scrollSnapAlign = `${positions[blockDirection.value]} ${
          positions[inlineDirection.value]
        }`;
      }

      function setSST() {
        if (stop.checked) {
          rules[0].style.scrollSnapStop = "always";
        } else {
          rules[0].style.scrollSnapStop = "normal";
        }
      }
    </script>
  </body>
</html>
